clipboard: Add infrastructure to store clipboards
authorBenjamin Otte <otte@redhat.com>
Wed, 29 Nov 2017 22:23:36 +0000 (23:23 +0100)
committerBenjamin Otte <otte@redhat.com>
Sun, 3 Dec 2017 04:46:48 +0000 (05:46 +0100)
Clipboard managers will be so happy once the backends actually implement
it!

gdk/gdkclipboard.c
gdk/gdkclipboard.h
gdk/gdkclipboardprivate.h

index b51e99acc29983f0bf51c2cfa3235720c201b87a..1e723d3b52bd00a162f951921da6be4b60ff7e46 100644 (file)
@@ -186,6 +186,44 @@ gdk_clipboard_real_claim (GdkClipboard       *clipboard,
   return TRUE;
 }
 
+static void
+gdk_clipboard_store_default_async (GdkClipboard        *clipboard,
+                                   int                  io_priority,
+                                   GCancellable        *cancellable,
+                                   GAsyncReadyCallback  callback,
+                                   gpointer             user_data)
+{
+  GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
+  GTask *task;
+
+  task = g_task_new (clipboard, cancellable, callback, user_data);
+  g_task_set_priority (task, io_priority);
+  g_task_set_source_tag (task, gdk_clipboard_store_default_async);
+
+  if (priv->local)
+    {
+      g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                               _("This clipboard cannot store data."));
+    }
+  else
+    {
+      g_task_return_boolean (task, TRUE);
+    }
+
+  g_object_unref (task);
+}
+
+static gboolean
+gdk_clipboard_store_default_finish (GdkClipboard  *clipboard,
+                                    GAsyncResult  *result,
+                                    GError       **error)
+{
+  g_return_val_if_fail (g_task_is_valid (result, clipboard), FALSE);
+  g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_clipboard_store_default_async, FALSE);
+
+  return g_task_propagate_boolean (G_TASK (result), error);
+}
+
 static void
 gdk_clipboard_read_local_write_done (GObject      *clipboard,
                                      GAsyncResult *result,
@@ -283,6 +321,8 @@ gdk_clipboard_class_init (GdkClipboardClass *class)
   object_class->finalize = gdk_clipboard_finalize;
 
   class->claim = gdk_clipboard_real_claim;
+  class->store_async = gdk_clipboard_store_default_async;
+  class->store_finish = gdk_clipboard_store_default_finish;
   class->read_async = gdk_clipboard_read_local_async;
   class->read_finish = gdk_clipboard_read_local_finish;
 
@@ -451,6 +491,84 @@ gdk_clipboard_get_content (GdkClipboard *clipboard)
   return priv->content;
 }
 
+/**
+ * gdk_clipboard_store_async:
+ * @clipboard: a #GdkClipboard
+ * @io_priority: the [I/O priority][io-priority]
+ *     of the request. 
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @callback: (scope async): callback to call when the request is satisfied
+ * @user_data: (closure): the data to pass to callback function
+ *
+ * Asynchronously instructs the @clipboard to store its contents remotely to
+ * preserve them for later usage. If the clipboard is not local, this function
+ * does nothing but report success.
+ *
+ * This function is called automatically when gtk_main() or #GtkApplication
+ * exit, so you likely don't need to call it.
+ **/
+void
+gdk_clipboard_store_async (GdkClipboard        *clipboard,
+                           int                  io_priority,
+                           GCancellable        *cancellable,
+                           GAsyncReadyCallback  callback,
+                           gpointer             user_data)
+{
+  GdkClipboardPrivate *priv = gdk_clipboard_get_instance_private (clipboard);
+
+  g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
+  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+  g_return_if_fail (callback != NULL);
+
+  if (priv->local)
+    {
+      return GDK_CLIPBOARD_GET_CLASS (clipboard)->store_async (clipboard,
+                                                               io_priority,
+                                                               cancellable,
+                                                               callback,
+                                                               user_data);
+    }
+  else
+    {
+      return gdk_clipboard_store_default_async (clipboard,
+                                                io_priority,
+                                                cancellable,
+                                                callback,
+                                                user_data);
+    }
+}
+
+/**
+ * gdk_clipboard_store_finish:
+ * @clipboard: a #GdkClipboard
+ * @result: a #GAsyncResult
+ * @error: a #GError location to store the error occurring, or %NULL to 
+ * ignore.
+ *
+ * Finishes an asynchronous clipboard store started with gdk_clipboard_store_async().
+ *
+ * Returns: %TRUE if storing was successful.
+ **/
+gboolean
+gdk_clipboard_store_finish (GdkClipboard  *clipboard,
+                            GAsyncResult  *result,
+                            GError       **error)
+{
+  g_return_val_if_fail (GDK_IS_CLIPBOARD (clipboard), FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  /* don't check priv->local here because it might have changed while the
+   * read was ongoing */
+  if (g_async_result_is_tagged (result, gdk_clipboard_store_default_async))
+    {
+      return gdk_clipboard_store_default_finish (clipboard, result, error);
+    }
+  else
+    {
+      return GDK_CLIPBOARD_GET_CLASS (clipboard)->store_finish (clipboard, result, error);
+    }
+}
+
 static void
 gdk_clipboard_read_internal (GdkClipboard        *clipboard,
                              GdkContentFormats   *formats,
@@ -511,6 +629,7 @@ gdk_clipboard_read_async (GdkClipboard        *clipboard,
 
   g_return_if_fail (GDK_IS_CLIPBOARD (clipboard));
   g_return_if_fail (mime_types != NULL && mime_types[0] != NULL);
+  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
   g_return_if_fail (callback != NULL);
 
   formats = gdk_content_formats_new (mime_types, g_strv_length ((char **) mime_types));
index 61dad189270c4eb0e62851b16fb1ddbb54701c07..87f873aa2ac3f7578c84541995a40891e94883aa 100644 (file)
@@ -46,6 +46,17 @@ gboolean                gdk_clipboard_is_local          (GdkClipboard          *
 GDK_AVAILABLE_IN_3_94
 GdkContentProvider *    gdk_clipboard_get_content       (GdkClipboard          *clipboard);
 
+GDK_AVAILABLE_IN_3_94
+void                    gdk_clipboard_store_async       (GdkClipboard          *clipboard,
+                                                         int                    io_priority,
+                                                         GCancellable          *cancellable,
+                                                         GAsyncReadyCallback    callback,
+                                                         gpointer               user_data);
+GDK_AVAILABLE_IN_3_94
+gboolean                gdk_clipboard_store_finish      (GdkClipboard          *clipboard,
+                                                         GAsyncResult          *result,
+                                                         GError               **error);
+
 GDK_AVAILABLE_IN_3_94
 void                    gdk_clipboard_read_async        (GdkClipboard          *clipboard,
                                                          const char           **mime_types,
index ec6dc208d6e8dfe9e81c5cd5cf5976ba562b1d5d..1a511a103144371ee3e2713d016ef05c360ec294 100644 (file)
@@ -45,6 +45,14 @@ struct _GdkClipboardClass
                                                                  GdkContentFormats      *formats,
                                                                  gboolean                local,
                                                                  GdkContentProvider     *content);
+  void                  (* store_async)                         (GdkClipboard           *clipboard,
+                                                                 int                     io_priority,
+                                                                 GCancellable           *cancellable,
+                                                                 GAsyncReadyCallback     callback,
+                                                                 gpointer                user_data);
+  gboolean              (* store_finish)                        (GdkClipboard           *clipboard,
+                                                                 GAsyncResult           *result,
+                                                                 GError                **error);
   void                  (* read_async)                          (GdkClipboard           *clipboard,
                                                                  GdkContentFormats      *formats,
                                                                  int                      io_priority,